This package implements the various Common
Lisp features of defmacro, such as destructuring,
&environment, and &body.
Top-level &whole is not implemented for
defmacro due to technical difficulties. See Argument Lists.
Destructuring is made available to the user by way of the following macro:
This macro expands to code which executes forms, with the variables in arglist bound to the list of values returned by expr. The arglist can include all the features allowed for
defmacroargument lists, including destructuring. (The&environmentkeyword is not allowed.) The macro expansion will signal an error if expr returns a list of the wrong number of arguments or with incorrect keyword arguments.
This package also includes the Common Lisp
define-compiler-macro facility, which allows you to
define compile-time expansions and optimizations for your
functions.
This form is similar to
defmacro, except that it only expands calls to name at compile-time; calls processed by the Lisp interpreter are not expanded, nor are they expanded by themacroexpandfunction.The argument list may begin with a
&wholekeyword and a variable. This variable is bound to the macro-call form itself, i.e., to a list of the form ‘(name args...)’. If the macro expander returns this form unchanged, then the compiler treats it as a normal function call. This allows compiler macros to work as optimizers for special cases of a function, leaving complicated cases alone.For example, here is a simplified version of a definition that appears as a standard part of this package:
(define-compiler-macro member* (&whole form a list &rest keys) (if (and (null keys) (eq (car-safe a) 'quote) (not (floatp-safe (cadr a)))) (list 'memq a list) form))This definition causes
(member*a list)to change to a call to the fastermemqin the common case where a is a non-floating-point constant; if a is anything else, or if there are any keyword arguments in the call, then the originalmember*call is left intact. (The actual compiler macro formember*optimizes a number of other cases, including common:testpredicates.)
This function is analogous to
macroexpand, except that it expands compiler macros rather than regular macros. It returns form unchanged if it is not a call to a function for which a compiler macro has been defined, or if that compiler macro decided to punt by returning its&wholeargument. Likemacroexpand, it expands repeatedly until it reaches a form for which no further expansion is possible.
See Macro
Bindings, for descriptions of the macrolet and
symbol-macrolet forms for making “local”
macro definitions.